//入口文件

const { src, dest , parallel , series , watch} = require('gulp')
//sass工作的时候如果文件名前带下划线的不会打包到下面规定的路径上


//自动加载插件
const loadPlugins = require('gulp-load-plugins')
//使用方法
const plugins = loadPlugins()
//同时下面的方法名字也需要改动,这里就可以注释不要用了
// const plugins.sass = require('gulp-sass')
// const plugins.babel = require('gulp-babel')
//const plugins.swig = require('gulp-swig')
//const plugins.imagemin = require('gulp-imagemin')


//因为使用了自动安装插件gulp-load-plugins
// const sass = require('gulp-sass')
//使用babel还需要安装==@babel/core @babel/preset-env
// const babel = require('gulp-babel')

//页面模板编译
// const swig = require('gulp-swig')

//图片和文字转换
// const imagemin = require('gulp-imagemin')

//useref----yarn add gulp-useref---用于文件引用处理
// const useref = require('gulp-useref')


//清除---这不是gulp插件
const del = require('del')
const browserSync = require('browser-sync')

//首先安装yarn add browser-sync --dev
//这个模块提供一个create方用于创建一个开发服务器
const bs = browserSync.create()

const data = {
  menus: [
    {
      name: 'Home',
      icon: 'aperture',
      link: 'index.html'
    },
    {
      name: 'Features',
      link: 'features.html'
    },
    {
      name: 'About',
      link: 'about.html'
    },
    {
      name: 'Contact',
      link: '#',
      children: [
        {
          name: 'Twitter',
          link: 'https://twitter.com/w_zce'
        },
        {
          name: 'About',
          link: 'https://weibo.com/zceme'
        },
        {
          name: 'divider'
        },
        {
          name: 'About',
          link: 'https://github.com/zce'
        }
      ]
    }
  ],
  pkg: require('./package.json'),
  date: new Date()
}



//清除---首先需要安装yarn add del --dev
const clean = () => { 
  //重新构建前
  // return del(['dist'])
  //重新构建后
   return del(['dist','temp'])
}

//样式编译
const style = () => { 
  //所有的css文件,base的目的就是把src后面的文件路径保留下来
  return src('src/assets/styles/*.scss', { base: 'src' })
    .pipe(plugins.sass())
    //重新构建前
    // .pipe(dest('dist'))
   //重新构建后
  .pipe(dest('temp'))
    // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

//js脚本编译
//需要在babel里面加上presets: ['@babel/env']
const script = () => { 
  return src('src/assets/scripts/*.js', { base: 'src' })
    .pipe(plugins.babel({ presets: ['@babel/env'] }))
    //重新构建前
    // .pipe(dest('dist'))
    //重新构建后
    .pipe(dest('temp'))
    // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

//脚本模板
const page = () => { 
  // 也可以使用--src/**/*.html 代表src下的全部html
  return src('src/*.html', { base: 'src' })
    .pipe(plugins.swig({ data }))
    //重新构建前
    // .pipe(dest('dist'))
    //重新构建后
    .pipe(dest('temp'))
  // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

//图片转换--压缩
const image = () => { 
  // **代表全部文件
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
  // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

//字体转换--压缩
const font = () => { 
  // **代表全部文件
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
  // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

//拷贝其他文件,例如public
const extra = () => {
  // public下面的所有文件
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
  // .pipe(bs.reload({stream:true}))如果下面serve本地服务器不用files方法监听那么就可以使用bs.reload方法以流的方式师刷新浏览器
}

const serve = () => { 
  //这是gulp的API
  // 第一个参数为监视路径,第二个为启动方法名称
  watch('src/assets/styles/*.scss', style)   //样式文件
  watch('src/assets/scripts/*.js', script)   //js脚本文件
  watch('src/*.html', page)                  //模板脚本文件
  //开发阶段没必要监听,这可以减少开销,提高效率
  // watch('src/assets/images/**', image)       //图片压缩
  // watch('src/assets/fonts/**', font)         //字体压缩
  // watch('public/**',extra)                   //其他文件
  // bs.reload下面路径文件发生变化就会刷新浏览器
watch(['src/assets/images/**','src/assets/fonts/**','public/**'],bs.reload)


  // init初始化一些相关的一些配置
  bs.init({
    //关闭网页右上角的提示
    notify: false,
    //开发服务器使用端口
    port: '8080',
    //是否自动打开浏览器
    open: 'true',
    //指定一个字符串,用于broeser启动过后被监听的文件
    files:'dist/**',
    //server这是最核心的一个配置
    server: {
      //网站的根目录,可以是一个数组,前面找不到他会依次往后面找
      // baseDir: 'dist',
      //重新构建前
      // baseDir:['dist','src','public'],
      //重新构建后
      baseDir:['temp','src','public'],
      //把/node_modules开头的请求指向node_modules的目录下,这个录音映射,并不能在线上去做
      //router的配置优先于baseDir
      routes:{
        '/node_modules':'node_modules'
      }
    }
  })
}

//useref---把之前的构建注释转换成链接
const useref = () => { 
  //重新构建前
  // return src('dist/*.html', { base: 'dist' })
    //重新构建后
  return src('temp/*.html', { base: 'temp' })
    //重新构建前
    // .pipe(plugins.useref({ searchPath: ['dist', '.'] }))
    //重新构建后
    .pipe(plugins.useref({ searchPath: ['temp', '.'] }))
    //代表以.js结尾---压缩
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    //没有配置的化只会压缩行内的一个空格minifyCSS,minifyJS这两个属性是压缩html中的css和jjs
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS:true
    })))
    //这里写入其他文件的原因是防止在同一文件中发生读写错误
    // .pipe(dest('release'))
   .pipe(dest('dist'))
}


//组合方法
// const compile = parallel(style,script,page,image,font)

//先执行clean,在执行其他
// const build = series(clean, parallel(compile, extra)) 



//优化
//把image和font移走放到build去,因为在开发阶段不需要提供watch监听
const compile = parallel(style,script,page)

  //上线之前执行
const build = series(clean, parallel(series(compile,useref),image,
  font, extra))

//开发阶段执行
const develop = series(compile,serve)

module.exports = {
  // style,
  // script,
  // page
  clean,//清除
  // compile,
  build,//上线前打包
  // serve,
  develop,//开发时启动
  // useref
}